#pragma once
#include <string>
#include <cstddef> // std::size_t

/*
 在 C++ 中，要使用 ODB 将类声明为持久化类，需要包含 ODB 的核心头文
件，并使用 #pragma db object 指令
 #pragma db object 指示 ODB 编译器将 person 类视为一个持久化类。
*/
#include <odb/core.hxx>
#include <odb/nullable.hxx>
#include <boost/date_time/posix_time/posix_time.hpp>

namespace bite_im
{
#pragma db object table("message")
    class Message
    {
    public:
        Message() {}

        Message(const std::string &message_id,
                const std::string &session_id,
                const std::string &user_id,
                unsigned char message_type,
                const boost::posix_time::ptime &create_time)
            : _message_id(message_id),
              _session_id(session_id),
              _user_id(user_id),
              _message_type(message_type),
              _create_time(create_time) {}

        void message_id(const std::string &val) { _message_id = val; }
        std::string message_id() const { return _message_id; }

        void session_id(const std::string &val) { _session_id = val; }
        std::string session_id() const { return _session_id; }

        void user_id(const std::string &val) { _user_id = val; }
        std::string user_id() const { return _user_id; }

        unsigned char message_type() const { return _message_type; }
        void message_type(unsigned char val) { _message_type = val; }

        void content(const std::string &val) { _content = val; }
        std::string content() const
        {
            if (!_content)
            {
                return std::string();
            }
            return *_content;
        }

        void file_id(const std::string &val) { _file_id = val; }
        std::string file_id() const
        {
            if (!_file_id)
            {
                return std::string();
            }
            return *_file_id;
        }

        void file_name(const std::string &val) { _file_name = val; }
        std::string file_name() const
        {
            if (!_file_name)
            {
                return std::string();
            }
            return *_file_name;
        }

        void file_size(const unsigned int &val) { _file_size = val; }
        unsigned int file_size() const
        {
            if (!_file_size)
            {
                return 0;
            }
            return *_file_size;
        }

        boost::posix_time::ptime create_time() const { return _create_time; }
        void create_time(const boost::posix_time::ptime &val) { _create_time = val; }

    private:
        friend class odb::access;
        //_id 成员前面的 pragma 告诉 ODB 编译器，以下成员是对象的标识符。auto 说明符指示它是数据库分配的 ID。
#pragma db id auto // 表示 ID 字段将自动生成（通常是数据库中的主键），在哪个上面就是主键
        unsigned long _id;

#pragma db type("varchar(64)") index
        std::string _session_id; // 所属会话id
#pragma db type("varchar(64)")
        std::string _user_id; // 发送者用户id
#pragma db type("varchar(64)") index
        std::string _message_id; // 消息id

        unsigned char _message_type; // 消息类型对应base.proto的MessageType

        odb::nullable<std::string> _content; // 文本消息内容
#pragma db type("varchar(64)")
        odb::nullable<std::string> _file_id; // 文件消息id --- 文本消息没有该字段
#pragma db type("varchar(128)")
        odb::nullable<std::string> _file_name;  // 文件名称 --- 文本消息没有该字段
        odb::nullable<unsigned int> _file_size; // 文件大小 --- 文本消息没有该字段

        boost::posix_time::ptime _create_time; // 消息产生时间

        // 将linux下的时间戳类型转为boost::posix_time类型
        // boost::posix_time::ptime ctime(boost::posix_time::from_time_t(时间戳类型));

        // 将boost::posix_time类型转为linux下的时间戳
        // message_info->set_timestamp(boost::posix_time::to_time_t(message.create_time()));
    };
}

// odb -d mysql --std c++11 --generate-query --generate-schema --profile boost/date-time message.hxx
//  生成数据库后记得进入message_sql来给ChatRoom生成表